$(function () {
    // global variable to configure refresh interval and timeout (in seconds!)
    var refreshInterval = 5;
    var refreshTimeout = 3;

    // calculate outdated warning thresholds
    var outDatedWarning = (refreshInterval * 3);
    var outDatedError = (refreshInterval * 10);

    // last updated timestamp global variable
    var lastUpdatedTimestamp = 0;

    // Gauge chart configuration options {{{
    var gauge_options = {
        palette: 'Soft Pastel',
        animation: {
            enabled: false
        },
        valueIndicator: {
            type: 'triangleNeedle',
            color: '#7a8288'
        },
        geometry: {
            startAngle: 180, 
            endAngle: 0
        },
        margin: {
            top: 0,
            right: 10
        },
        rangeContainer: {
            ranges: [
                { startValue: 0, endValue: 60, color: '#62c462' },
                { startValue: 60, endValue: 80, color: '#f89406' },
                { startValue: 80, endValue: 100, color: '#ee5f5b' }
            ]
        },
        scale: {
            startValue: 0, 
            endValue: 100,
            majorTick: {
                tickInterval: 20
            },
            label: {
                customizeText: function (arg) {
                    return arg.valueText + ' %';
                }
            }
        }
    };
    // }}}
    
    // Pie chart configuration options {{{
    var chart_options = {
        animation: {
            enabled: false
        },
        tooltip: {
            enabled: true,
            format:"decimal",
            percentPrecision: 2,
            font: { size: 10, color: '#1c1e22', family: 'Helvetica' },
            arrowLength: 10,
            customizeText: function() {
                return this.valueText + " - " + this.argumentText + " (" + this.percentText + ")";
            }
        },
        customizePoint: function (point) {
            if (point.argument.indexOf('active+clean') >= 0) {
                return {
                    color: '#62c462'
                }
            } else if (point.argument.indexOf('active') >= 0) {
                return {
                    color: '#f89406'
                }
            } else {
                return {
                    color: '#ee5f5b'
                }
            }
        },
        legend: {
            visible: false
        },
        series: [{
            type: "doughnut",
            argumentField: "name",
            valueField: "num",
            label: {
                visible: false,
            }
        }]
    };
    // }}}

    $.fn.extend({
        "slideUp":function(value){
            
            var docthis = this;
            //默认参数
            value=$.extend({
                 "li_h":"30",
                 "time":2000,
                 "movetime":1000
            },value)
            
            //向上滑动动画
            function autoani(){
                $("li:first",docthis).animate({"margin-top":-value.li_h},value.movetime,function(){
                    $(this).css("margin-top",0).appendTo(".line");
                })
            }
            
            //自动间隔时间向上滑动
            var anifun = setInterval(autoani,value.time);
            
            //悬停时停止滑动，离开时继续执行
            $(docthis).hover(function(){
                clearInterval(anifun);            //清除自动滑动动画
            },function(){
            	anifun = setInterval(autoani,value.time);
            })
        }    
    });
    
    // Convert bytes to human readable form {{{
    function fmtBytes(bytes) {
        if (bytes==0) { return "0 bytes"; }
        var s = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
        var e = Math.floor(Math.log(bytes) / Math.log(1024));
        return (bytes / Math.pow(1024, e)).toFixed(2) + " " + s[e];
    }
    // }}}

    // Initialize unhealthy osd popover {{{
    $("#unhealthy_osds").popover({
        html: true,
        placement: 'bottom',
        trigger: 'hover'
    });
    // }}}

    // MAKE SECTION COLLAPSABLE {{{
    $('.cd-collapsable').on("click", function (e) {
        if ($(this).hasClass('cd-collapsed')) {
            // expand the panel
            $(this).parents('.panel').find('.panel-body').slideDown();
            $(this).removeClass('cd-collapsed');
        }
        else {
            // collapse the panel
            $(this).parents('.panel').find('.panel-body').slideUp();
            $(this).addClass('cd-collapsed');
        }
    });
    // }}}

    // GENERIC AJAX WRAPER {{{
    function ajaxCall(url, callback) {
        $.ajax({
          url: url,
          dataType: 'json',
          type: 'GET',
          data: null,
          contentType: 'application/json',
          beforeSend : function() {},
          success: callback,
          error: function() {
              // refresh last updated timestamp
              timeStamp = Math.floor(Date.now() / 1000);
              timeDiff = timeStamp - lastUpdatedTimestamp;

              if (lastUpdatedTimestamp == 0) {
                  lastUpdatedTimestamp = timeStamp - refreshInterval;
                  timeDiff = refreshInterval;
              }


              if (timeDiff > outDatedWarning) {
                  msg = 'Content has last been refreshed more than ' + timeDiff + ' seconds before';
                  $('#last_update').show();
                  $('#last_update').tooltip({
                      placement: 'bottom',
                  });
                  $('#last_update').attr('data-original-title', msg);
              }
          },
          timeout: (refreshTimeout * 1000)
        });
    }
    // }}}

    // CREATE A ALERT MESSAGE {{{
    function message(severity, msg) {
        if (severity == 'success') { icon = 'ok' }
        if (severity == 'warning') { icon = 'flash' }
        if (severity == 'danger') { icon = 'remove' }
        return '<div class="alert alert-' + severity + '"><strong><span class="glyphicon glyphicon-' + icon + '">&nbsp;</span>' + msg + '</strong></div>';
    }
    // }}}

    // MESSAGE fro pool_status{{{
    function message02(msg){

        //return '<div class="alert alert-' + severity + '"><strong>' + msg + '</strong></div>';
        return '<div class="right"><strong>' + msg + '</strong></div>';

    }

    // }}}

    // MAPPING CEPH TO BOOTSTRAP {{{
    var ceph2bootstrap = {
        HEALTH_OK: 'success',
        HEALTH_WARN: 'warning',
        HEALTH_ERR: 'danger',
        down: 'warning',
        out: 'danger'
    }
    // }}}

    // INITIALIZE EMPTY PIE CHART {{{
    $("#pg_status").dxPieChart($.extend(true, {}, chart_options, {
        dataSource: []
    }));
    // }}}
    
    // overall status updated
    function updateOverallStatus() {
        callback = function(data, status, xhr) {
        	// *overall status*
            clusterStatusOverall = data['health']['overall_status'];
            clusterHealthSummary = data['health']['summary'];
            $("#overall_status_total").empty();
            $("#overall_status_total").append("<span class='glyphicon glyphicon-flash'></span>"+"Cluster Status:" + clusterStatusOverall);
            var innerHtml = "";
            // update overall cluster status details
            innerHtml += '<ul class="line">';
            $.each(clusterHealthSummary, function(index, obj) {
            	innerHtml += ("<li style='margin-top: 0px;'><span class='glyphicon glyphicon-flash'></span>"+obj['summary']+"</li>");
            });
            innerHtml += '</ul>';
            $("#overall_status").empty();
            $("#overall_status").append(innerHtml);
            $(".line").slideUp();
//            $("#overall_status").text('Cluster Status:' + clusterStatusOverall);
//            // update overall cluster state
//            $("#overall_status").empty();
//            $("#overall_status").append(message(ceph2bootstrap[clusterStatusOverall], 'Cluster Status:' + clusterStatusOverall));
//
//            // update overall cluster status details
//            $("#overall_status").append('<ul class="list-group">');
//            $.each(clusterHealthSummary, function(index, obj) {
//                $("#overall_status").append('<li class="list-group-item active"><span class="glyphicon glyphicon-flash"></span><strong>' + obj['summary'] + '</strong></li>');
//            });
//            $("#overall_status").append('</ul>');
        }
        ajaxCall(window.location.pathname+"/updated_overall_status", callback);
    }
    updateOverallStatus();
//    setInterval(updateOverallStatus, (refreshInterval * 1000));
    
    // host status updated
    function updateHostStatus() {
        callback = function(data, status, xhr) {
        	pool_count   = data['pool_count'];
            client_count = data['client_count'];
            server_count = data['server_count'];
            // update host state
            $("#clientCount").text(client_count);
            $("#serverCount").text(server_count);
            $("#poolCount").text(pool_count);
        }
        ajaxCall(window.location.pathname+"/updated_host_status", callback);
    }
    updateHostStatus();
    setInterval(updateHostStatus, (refreshInterval * 1000));
    
    // monmap updated
    function updateMonMap() {
    	callback = function(data, status, xhr) {
    		monmapMons = data['monmap']['mons'];
    		timechekMons = data['timechecks'];
//    		alert(timechekMons);
            var mon_total = timechekMons.length
            var mon_ok = 0;
            var mon_warn = 0;
            var mon_err = 0;
            
            $.each(timechekMons, function(index, mon_health) {
                if (mon_health['health'] == "HEALTH_OK") {
                	mon_ok += 1;
                }else if( mon_health['health'] == "HEALTH_WARN" ){
                	mon_warn += 1;
                }else if( mon_health['health'] == "HEALTH_ERR" ){
                	mon_err += 1;
                }
            });
            
            $("#mon_ok").text(mon_ok + "/" + mon_total);
            $("#mon_warn").text(mon_warn + "/" + mon_total);
            $("#mon_err").text(mon_err + "/" + mon_total);
            
    		// update monitor status
//          $("#monitor_status").empty();
//            
//            $.each(monmapMons, function(index, mon) {
//                health = 'HEALTH_ERR'
//                $.each(timechekMons, function(index, mon_health) {
//                    if (mon['name'] == mon_health['name']) {
//                        health = mon_health['health'];
//                    }
//                });
//                msg = 'Monitor ' + mon['name'].toUpperCase() + ': ' + health;
//                $("#monitor_status").append('<div class="col-md-4">' + message(ceph2bootstrap[health], msg) + '</div>');
//            });
    	}
    	ajaxCall(window.location.pathname+"/updated_monmap", callback);
    }
    updateMonMap();
    setInterval(updateMonMap, (refreshInterval * 1000));
    
    // osd updated
    function updateOsd() {
    	callback = function(data, status, xhr) {
    		// *osd state*
            numOSDtotal = data['osdmap']['osdmap']['num_osds'] || 0;
            numOSDin = data['osdmap']['osdmap']['num_in_osds'] || 0;
            numOSDup = data['osdmap']['osdmap']['num_up_osds'] || 0;
            numOSDunhealthy = data['osdmap']['osdmap']['num_osds'] - data['osdmap']['osdmap']['num_up_osds'] || 0;
            unhealthyOSDDetails = data['osdmap']['details'];
            osdFull = data['osdmap']['osdmap']['full'];
            osdNearFull = data['osdmap']['osdmap']['nearfull'];
            
//           // update OSD states
//            $("#num_osds").html(numOSDtotal);
            $("#num_in_osds").html(numOSDin);
            $("#num_in_osds").css("width",(numOSDup/numOSDtotal)*100+"%");
            $("#num_up_osds").html(numOSDup);
            $("#num_up_osds").css("width",(numOSDup/numOSDtotal)*100+"%");
//            $("#unhealthy_osds").html(numOSDunhealthy);
            
//           // update unhealthy osd popover if there are any unhealthy osds
//            if(unhealthyOSDDetails.length > 0){
//	            osdPopover = $('#unhealthy_osds').data('bs.popover');
//	            osdPopover.options.content = '';
//	            if (typeof(unhealthyOSDDetails) != 'undefined') {
//	                osdPopover.options.content += '<table class="table table-condensed">';
//	                $.each(unhealthyOSDDetails, function(index, osd_stats) {
//	                    osdPopover.options.content += '<tr>';
//	                    osdPopover.options.content += '<td class="text-' + ceph2bootstrap[osd_stats.status] + '">' + osd_stats.status + '</td>';
//	                    osdPopover.options.content += '<td>' + osd_stats.name + '</td>';
//	                    osdPopover.options.content += '<td>' + osd_stats.host + '</td>';
//	                    osdPopover.options.content += '</tr>';
//	                });
//	                osdPopover.options.content += '</table>';
//	            }
//            }
//
//            // update osd full / nearfull warnings
//            $("#osd_warning").empty();
//            if (osdFull == "true") {
//                $("#osd_warning").append(message('danger', 'OSD FULL ERROR'));
//            }
//            if (osdNearFull == "true") {
//                $("#osd_warning").append(message('warning', 'OSD NEARFULL WARNING'));
//            }
    	}
    	ajaxCall(window.location.pathname+"/updated_osd", callback);
    }
    updateOsd();
    setInterval(updateOsd, (refreshInterval * 1000));
    
//    // pool updated
//    function updatePool() {
//    	callback = function(data, status, xhr) {
//    		// pool status*
//            pools = data['pool'];
//            //img = data['pool']['name'];
//            //console.log(img);
//            
//            $("#pool_sum").empty();
//            $("#dialog_sum").empty();
//            $.each(pools, function(index, pool) {
//             //   $.each(timecheklun, function(index, lun_name) {
//             //       if (pool['name'] == lun_name['name']) {
//             //           health = mon_health['health'];
//             //       }
//             //   });
//                pool_name = pool['name'];
//                pool_max = pool['stats']['max_avail'] || 0;
//                pool_used = pool['stats']['bytes_used'] || 0;
//                pool_id =  pool['id'];
//                pool_usage_rate = pool_used / pool_max;
//                img = pool['img'];
//                dialog_pool = "dialog" + pool_id;
//                //console.log(img);
//                if ( pool_usage_rate <= 0.7 ) {
//                    health = 'HEALTH_OK';
//                }
//                else if ( pool_usage_rate <= 0.8 ) {
//                    health = 'HEALTH_WARN';
//                }
//                else {
//                    health = 'HEALTH_ERR';
//                }
//
//                //$("#pool_sum").append('<div class="col-md-4">' + message(ceph2bootstrap[health], pool_name + fmtBytes(pool_used) + '/' + fmtBytes(pool_max))  +  '</div>');
//                $("#pool_sum").append('<div class="col-md-4" id="'+pool_id+'">' + message(ceph2bootstrap[health], pool_name  + message02(fmtBytes(pool_used) + '/' + fmtBytes(pool_max)))  +  '</div>');
//                var name = new Array();
//                $("#dialog_sum").append('<div  id="'+dialog_pool+'" title="'+pool_name+'" style="display: none;"></div>');
//            	$.each(img, function(index, imgs) {
//                    img_name = imgs['img_name'];
//                    img_size = imgs['img_size'];
//                    img_id = imgs['img_id'];
//                    name[img_id] = img_name;
////                        console.log(img_info);
//                    //$("#pool_sum").append('<script type="text/javascript">' + '$(document).ready(function(){$("#' + pool_id + '").on("click",function(a){alert("'+ img_name + '");});});' + '</script>');
//                    //$("#pool_sum").append('<script type="text/javascript">' + '$("#' + pool_id + '").on("click",function(a){alert("'+ img_name + '");});' + '</script>');
//                    //$("#'+ pool_id +'").append('<div>' + message(img_name + message02(fmtBytes(img_size))) + '</div>');
//                    $("#"+dialog_pool).append( '<div class="col-md-4" id="'+img_id+'">' + message(ceph2bootstrap[health], img_name + message02(fmtBytes(img_size)))+  '</div>');
//                    });
//
//	           // console.log(dialog_pool);
//	            //$("#pool_sum").append('<script type="text/javascript">' + '$("#' + pool_id + '").on("click",function(a){alert("'+ name[1] + '");});' + '</script>');
//	            $("#pool_sum").append('<script type="text/javascript">' + '$("#' + pool_id + '").on("click",function(a){$("#'+dialog_pool+'").css({display:"block"});$("#'+dialog_pool+'").dialog({maxHeight:600,width:850});});' + '</script>');
//	            //$("#pool_sum").append('<div id="'+dialog_pool+'" title="'+pool_name+'">a</div>');
//	            //$("#dialog_sum").append('<div id="'+dialog_pool+'" title="'+pool_name+'" style="display: none">' + message(ceph2bootstrap[health], img_name + message02(fmtBytes(img_size))) + '</div>');
//	
//	
//	
//	            //$("#pool_sum").append('<script type="text/javascript">' +  '$("#'+pool_id+'").on("click",function(a){alert('+pool_id+');});' +  '</script>');
//	            //console.log(pool_id)
//                
//            });
//
//    	}
//    	ajaxCall(window.location.pathname+"/updated_pool", callback);
//    }
//    updatePool();
//    setInterval(updatePool, (refreshInterval * 1000 * 2));
    
    //pgmap updated
    function updatePgMap() {
    	callback = function(data, status, xhr) {
    		// *storage capacity*
            bytesTotal = data['pgmap']['bytes_total'];
            bytesUsed = data['pgmap']['bytes_used'];
            percentUsed = Math.round((bytesUsed / bytesTotal) * 100);

            // *placement groups*
            pgsByState = data['pgmap']['pgs_by_state'];
            numPgs = data['pgmap']['num_pgs'];

            // *throughput* 
            opsPerSec = data['pgmap']['op_per_sec'] || 0;
            writesPerSec = fmtBytes(data['pgmap']['write_bytes_sec'] || 0);
            readsPerSec = fmtBytes(data['pgmap']['read_bytes_sec'] || 0);
            
         // Update Content {{{
            // ----------------------------------------------------------------
            // update storage capacity
            $("#utilization").dxCircularGauge($.extend(true, {}, gauge_options, {
                value: percentUsed
            }));
            $("#utilization_info").html(fmtBytes(bytesUsed) + " / " + fmtBytes(bytesTotal) + " (" + percentUsed + "%)");

            // update placement group chart
            var chart = $("#pg_status").dxPieChart("instance");
            chart.option('dataSource', pgsByState);

            $("#pg_status_info").html(numPgs + "  虚拟节点");

            // update current throughput values
            $("#operations_per_second").html(opsPerSec);
            $("#write_bytes").html(writesPerSec);
            $("#read_bytes").html(readsPerSec);
            
    	}
    	ajaxCall(window.location.pathname+"/updated_pgmap", callback);
    }
    updatePgMap();
    setInterval(updatePgMap, (refreshInterval * 1000));
    
    //Alarm time
    function updateDiskDetection() {
    	callback = function(result, status, xhr) {
    		if(result.result=='success'){
    			 $('#scatter').highcharts({
    				 chart: {
    					    height: 310,
				            type: 'bar'   
				        },
				        title: {
				            text: "慢盘检测"
				        },
				        xAxis: {
				            categories:result.osdName,
				            labels: {
				            	overflow: 'justify', 
				                style: {
				                    fontSize: '9px',
				                    fontFamily: 'Verdana, sans-serif'
				                },
				            }
				        },
				        yAxis: {
				            min: 0,
				            title: {
				                text: 'Alarm (time)'
				            }
				        },
				        legend: {
				            enabled: false
				        },
				        tooltip: {
				            pointFormat: '<b>{point.y:.0f} time</b>',
				        },
				        series: [{
				            name: 'Population',
				            data: result.alarmCount,
				            dataLabels: {
				                enabled: true,
				                rotation: 0,
				                color: '#FFFFFF',
				                align: 'center',
				                x: 4,
				                y: 4,
				                style: {
				                    fontSize: '9px',
				                    fontFamily: 'Verdana, sans-serif',
				                    textShadow: '0 0 3px black'
				                }
				            }
				        }]                               
				    });
			}
    	}
    	ajaxCall(window.location.pathname+"/getOsdAndAlarmCount", callback);
    }
    updateDiskDetection();
    setInterval(updateDiskDetection, (refreshInterval * 10000));
    
    // read
    function loadRead() {
    	callback = function(data, status, xhr) {
			  $('#node_read').highcharts({ 
			        chart: { 
			            defaultSeriesType: 'line', //图表类型line(折线图), 
			            height: 300,
		            	events: { 
		                    load: function() {  
		                        var series = this.series[0]; 
		                        
		                        //每隔5秒钟，图表更新一次
		                        setInterval(function() { 
		                        	callback = function(data, status, xhr) {
		                        		var x = data['categories'][0];
		                        		var y = data['series'][0]['data'][0];
		                        		series.addPoint([x, y], true, true); 
			                        }
		                            ajaxCall(window.location.pathname+"/updated_read", callback);
		                        }, 
		                        5000); 
		                    } 
		                } 
			        }, 
			        title: {
			            text: '读/秒', //图表标题
			            aligh: 'left'
			        }, 
			        xAxis: {  //x轴 
			            categories: data['categories'],
			            gridLineWidth: 1, //设置网格宽度为1 
			            lineWidth: 2,  //基线宽度 
			            labels:{y:26}  //x轴标签位置：距X轴下方26像素 
			        }, 
			        yAxis: {  //y轴 
			            title: {text: ''}, //标题 
			            lineWidth: 2 //基线宽度 
			        }, 
			        legend: { 
			            enabled: false  //设置图例不可见 
			        }, 
			        exporting: { 
			            enabled: false  //设置导出按钮不可用 
			        },
			        tooltip: {//当鼠标悬置数据点时的提示框 
			            formatter: function() { //格式化提示信息 
			                return fmtBytes(this.y); 
			            } 
			        },
			        series: data['series']
			    });
		}
    	ajaxCall(window.location.pathname+"/read_onload", callback);
    }
    loadRead();
//    setInterval(loadRead, (refreshInterval * 1000));
    
    // write
    function loadWrite() {
    	callback = function(data, status, xhr) {
			  $('#node_write').highcharts({ 
			        chart: { 
			            defaultSeriesType: 'line', //图表类型line(折线图), 
			            height: 300,
		            	events: { 
	                    load: function() {  
	                        var series = this.series[0]; 
	                        
	                        //每隔5秒钟，图表更新一次，y数据值在0-100之间的随机数 
	                        setInterval(function() { 
	                        	callback = function(data, status, xhr) {
	                        		var x = data['categories'][0];
	                        		var y = data['series'][0]['data'][0];
	                        		series.addPoint([x, y], true, true); 
		                        }
	                            ajaxCall(window.location.pathname+"/updated_write", callback);
	                        }, 
	                        5000); 
	                    } 
	                } 
			        }, 
			        title: {
			            text: '写/秒', //图表标题
			            aligh: 'left'
			        }, 
			        xAxis: {  //x轴 
			            categories: data['categories'],
			            gridLineWidth: 1, //设置网格宽度为1 
			            lineWidth: 2,  //基线宽度 
			            labels:{y:26}  //x轴标签位置：距X轴下方26像素 
			        }, 
			        yAxis: {  //y轴 
			            title: {text: ''}, //标题 
			            lineWidth: 2 //基线宽度 
			        }, 
			        legend: { 
			            enabled: false  //设置图例不可见 
			        }, 
			        exporting: { 
			            enabled: false  //设置导出按钮不可用 
			        },
			        tooltip: {//当鼠标悬置数据点时的提示框 
			            formatter: function() { //格式化提示信息 
			                return fmtBytes(this.y); 
			            } 
			        },
			        series: data['series']
			    });
		}
    	ajaxCall(window.location.pathname+"/write_onload", callback);
    }
    loadWrite();
//    setInterval(loadWrite, (refreshInterval * 1000));
    
 // operations
    function loadOperations() {
    	callback = function(data, status, xhr) {
			  $('#node_operations').highcharts({ 
			        chart: { 
			            defaultSeriesType: 'line', //图表类型line(折线图), 
			            height: 300,
			            events: { 
		                    load: function() {  
		                        var series = this.series[0]; 
		                        
		                        //每隔5秒钟，图表更新一次，y数据值在0-100之间的随机数 
		                        setInterval(function() { 
		                        	callback = function(data, status, xhr) {
		                        		var x = data['categories'][0];
		                        		var y = data['series'][0]['data'][0];
		                        		series.addPoint([x, y], true, true); 
			                        }
		                            ajaxCall(window.location.pathname+"/updated_operations", callback);
		                        }, 
		                        5000); 
		                    } 
		                } 
			        }, 
			        title: {
			            text: '操作数/秒', //图表标题
			            aligh: 'left'
			        }, 
			        xAxis: {  //x轴 
			            categories: data['categories'],
			            gridLineWidth: 1, //设置网格宽度为1 
			            lineWidth: 2,  //基线宽度 
			            labels:{y:26}  //x轴标签位置：距X轴下方26像素 
			        }, 
			        yAxis: {  //y轴 
			            title: {text: ''}, //标题 
			            lineWidth: 2 //基线宽度 
			        }, 
			        legend: { 
			            enabled: false  //设置图例不可见 
			        }, 
			        exporting: { 
			            enabled: false  //设置导出按钮不可用 
			        },
			        tooltip: {//当鼠标悬置数据点时的提示框 
			            formatter: function() { //格式化提示信息 
			                return this.y; 
			            } 
			        },
			        series: data['series']
			    });
		}
    	ajaxCall(window.location.pathname+"/operations_onload", callback);
    }
    loadOperations();
//    setInterval(loadOperations, (refreshInterval * 1000));
})



// vim: set foldmethod=marker foldlevel=0 ts=4 sts=4 filetype=javascript fileencoding=utf-8 formatoptions+=ro expandtab:
